home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
QRZ! Ham Radio 8
/
QRZ Ham Radio Callsign Database - Volume 8.iso
/
mac
/
files
/
infodata
/
callbook.tar
/
callbook_1.3
/
telnet.c
< prev
next >
Wrap
C/C++ Source or Header
|
1991-08-27
|
9KB
|
666 lines
/*
* Telnet callsign server sources copyright 1989 by Devon Bowen, KA2NRC.
* You may distribute and modify these files as you please as long as
* as long as credit to the original creator is given. Please report any
* bug fixes or modification to bowen@cs.buffalo.edu.
*/
#include <syslog.h>
#include <stdio.h>
#include <arpa/telnet.h>
int curr_row=0;
int max_row=23;
int in_echo=0, in_sga=0; /* only two options supported */
unsigned char readchar();
tinit()
{
unsigned char request[6], ch;
in_echo = in_sga = 1;
request[0] = IAC;
request[1] = WILL;
request[2] = TELOPT_ECHO;
request[3] = IAC;
request[4] = WILL;
request[5] = TELOPT_SGA;
if (write(1, request, 6) == -1) {
syslog(LOG_ERR, "%m");
exit(1);
}
while (in_echo == 1 || in_sga == 1) {
ch = readchar();
check_state(&ch);
}
}
will(option)
int option;
{
unsigned char request[3], ch;
int *watch;
switch (option) {
case TELOPT_ECHO : if (in_echo == 2) return(0);
watch = &in_echo;
in_echo = 1;
break;
case TELOPT_SGA : if (in_sga == 2) return(0);
watch = &in_sga;
in_sga = 1;
break;
}
request[0] = IAC;
request[1] = WILL;
request[2] = option;
if (write(1, request, 3) == -1) {
syslog(LOG_ERR, "%m");
exit(1);
}
while (*watch == 1) {
ch = readchar();
check_state(&ch);
}
}
char
tgetchar()
{
char ch;
static char nextchar = 0;
if (nextchar) {
ch = nextchar;
nextchar = 0;
} else {
ch = readchar();
while (!check_state(&ch) || ch == '\0')
ch = readchar();
}
if (ch == '\n')
if ((ch = readchar()) == '\r')
return('\n');
else {
nextchar = ch;
return('\n');
}
if (ch == '\r')
if ((ch = readchar()) == '\n')
return('\n');
else {
nextchar = ch;
return('\n');
}
return(ch);
}
char *
tgets(buf, size)
char *buf;
int size;
{
int cnt = 0 ;
char *ind = buf, ch = 'a';
curr_row = 0;
while (ch != '\0') {
switch (ch = tgetchar()) {
case '\177' : /* delete */
case '\010' : /* control h */
if (!in_sga) {
if (cnt <= size) {
if (in_echo && cnt < size)
echo(ch);
*ind = ch;
ind++;
cnt++;
}
break;
}
if (cnt != 0) {
if (*(ind-1) < 040)
send_ec(2);
else
send_ec(1);
cnt--;
ind--;
}
break;
case '\025' : /* control u */
case '\030' : /* control x */
if (!in_sga) {
if (cnt <= size) {
if (in_echo && cnt < size)
echo(ch);
*ind = ch;
ind++;
cnt++;
}
break;
}
if (cnt != 0)
for (; cnt > 0; cnt--) {
if (*(ind-1) < 040)
send_ec(2);
else
send_ec(1);
ind--;
}
break;
case '\027' : /* control w */
if (!in_sga) {
if (cnt <= size) {
if (in_echo && cnt < size)
echo(ch);
*ind = ch;
ind++;
cnt++;
}
break;
}
if (cnt != 0) {
while (*(ind-1) == ' ' && cnt > 0) {
if (*(ind-1) < 040)
send_ec(2);
else
send_ec(1);
cnt--;
ind--;
}
while (*(ind-1) != ' ' && cnt > 0) {
if (*(ind-1) < 040)
send_ec(2);
else
send_ec(1);
cnt--;
ind--;
}
}
break;
case '\n' :
if (in_echo)
echo(ch);
if (cnt <= size) {
*ind = '\0';
return(buf);
} else
return(NULL);
default :
if (in_echo)
echo(ch);
if (cnt <= size) {
*ind = ch;
ind++;
cnt++;
}
break;
}
}
}
tputs(str, send_ga)
char *str;
{
char buffer[BUFSIZ];
int bufcnt=0, limit;
static int curr_col=0;
limit = BUFSIZ - 10;
for (; *str; str++) {
if (*str == '\n') {
buffer[bufcnt++] = '\r';
buffer[bufcnt++] = '\n';
curr_row++;
curr_col = 0;
if (max_row && curr_row == max_row) {
if (write(1, buffer, bufcnt) == -1) {
syslog(LOG_ERR, "%m");
exit(1);
}
bufcnt = 0;
curr_col = 0;
if (write(1, "-- more --", 10) == -1) {
syslog(LOG_ERR, "%m");
exit(1);
}
switch (tgetchar()) {
case 'q' :
curr_row = 0;
send_ec(10);
return 1;
case ' ' :
curr_row = 0;
break;
default :
curr_row--;
break;
}
send_ec(10);
}
} else if (*str < 040) {
buffer[bufcnt++] = '^';
buffer[bufcnt++] = *str + 0100;
curr_col += 2;
} else {
buffer[bufcnt++] = *str;
curr_col++;
if (curr_col == 80) {
curr_col = 0;
curr_row++;
}
if (max_row && curr_row == max_row) {
if (write(1, buffer, bufcnt) == -1) {
syslog(LOG_ERR, "%m");
exit(1);
}
bufcnt = 0;
curr_col = 0;
if (write(1, "-- more --", 10) == -1) {
syslog(LOG_ERR, "%m");
exit(1);
}
switch (tgetchar()) {
case 'q' :
curr_row = 0;
send_ec(10);
return 1;
case ' ' :
curr_row = 0;
break;
default :
curr_row--;
break;
}
send_ec(10);
}
}
if (bufcnt > limit) {
if (write(1, buffer, bufcnt) == -1) {
syslog(LOG_ERR, "%m");
exit(1);
}
bufcnt = 0;
}
}
if (bufcnt != 0)
if (write(1, buffer, bufcnt) == -1) {
syslog(LOG_ERR, "%m");
exit(1);
}
if (send_ga && !in_sga) {
buffer[0] = IAC;
buffer[1] = GA;
if (write(1, buffer, 2) == -1) {
syslog(LOG_ERR, "%m");
exit(1);
}
}
return 0;
}
#define NORMAL 1
#define GOT_IAC 2
#define GOT_DO 3
#define GOT_DONT 4
#define GOT_WILL 5
#define GOT_WONT 6
check_state(next)
unsigned char *next;
{
static int state = NORMAL;
switch (state) {
case NORMAL : if (*next == IAC) {
state = GOT_IAC;
return(0);
}
return(1);
case GOT_IAC : switch (*next) {
case DO :
state = GOT_DO;
return(0);
case DONT :
state = GOT_DONT;
return(0);
case WILL :
state = GOT_WILL;
return(0);
case WONT :
state = GOT_WONT;
return(0);
case IAC :
state = NORMAL;
return(1);
case EC :
state = NORMAL;
*next = '\010';
return(1);
case EL :
state = NORMAL;
*next = '\025';
return(1);
default :
state = NORMAL;
return(0);
}
case GOT_DO : switch (*next) {
case TELOPT_ECHO :
if (in_echo != 1)
ack_will(*next);
in_echo = 2;
break;
case TELOPT_SGA :
if (in_sga != 1)
ack_will(*next);
in_sga = 2;
break;
default :
ack_wont(*next);
break;
}
state = NORMAL;
return(0);
case GOT_DONT : switch (*next) {
case TELOPT_ECHO :
if (in_echo == 1)
in_echo = 0;
else {
in_echo = 0;
ack_wont(*next);
}
break;
case TELOPT_SGA :
if (in_sga == 1)
in_sga = 0;
else {
in_sga = 0;
ack_wont(*next);
}
break;
}
state = NORMAL;
return(0);
case GOT_WILL : ack_dont(*next);
state = NORMAL;
return(0);
case GOT_WONT : state = NORMAL;
return(0);
}
}
unsigned char
readchar()
{
static int cc = 0;
static unsigned char *ind, buf[BUFSIZ];
if (!cc) {
switch (cc = read(0, buf, BUFSIZ-1)) {
case -1 : syslog(LOG_ERR, "%m");
exit(1);
case 0 : syslog(LOG_ERR, "socket closed");
exit(1);
}
ind = buf;
} else
ind++;
cc--;
return(*ind);
}
ack_will(option)
unsigned char option;
{
unsigned char request[3];
request[0] = IAC;
request[1] = WILL;
request[2] = option;
if (write(1, request, 3) == -1) {
syslog(LOG_ERR, "%m");
exit(1);
}
}
ack_wont(option)
unsigned char option;
{
unsigned char request[3];
request[0] = IAC;
request[1] = WONT;
request[2] = option;
if (write(1, request, 3) == -1) {
syslog(LOG_ERR, "%m");
exit(1);
}
}
ack_dont(option)
unsigned char option;
{
unsigned char request[3];
request[0] = IAC;
request[1] = DONT;
request[2] = option;
if (write(1, request, 3) == -1) {
syslog(LOG_ERR, "%m");
exit(1);
}
}
echo(what)
char what;
{
char temp[2];
if (what == '\n') {
temp[0] = '\r';
temp[1] = '\n';
if (write(1, temp, 2) == -1) {
syslog(LOG_ERR, "%m");
exit(1);
}
} else if (what < 040) {
temp[0] = '^';
temp[1] = what + 0100;
if (write(1, temp, 2) == -1) {
syslog(LOG_ERR, "%m");
exit(1);
}
} else {
temp[0] = what;
if (write(1, temp, 1) == -1) {
syslog(LOG_ERR, "%m");
exit(1);
}
}
}
send_ec(count)
int count;
{
int i;
char temp[BUFSIZ];
count *= 3;
for (i=0; i < count; i+=3) {
temp[i] = '\010';
temp[i+1] = '\040';
temp[i+2] = '\010';
}
if (write(1, temp, count) == -1) {
syslog(LOG_ERR, "%m");
exit(1);
}
}